"""
plasticity.py

Thu Oct 11 11:12:18 CEST 2012

This files contain the different learning rules to be applied
on connectivity matrix (W) to memorize a list of patterns
"""
import numpy as np

def clipped_Hebbian(Z, W):
    """
    Arguments:

    Z       -- object pattern (where Z.[i] is a NumPy array) 
    W       -- a NumPy array with the connectivity matrix

    storages the pattern or the sequence of patterns in 
    the network W according to a clipped Hebbian rule:
    the pattern is the representation of the activity of n neurons
    (see in Pattern object in firings.py) as a sequence of zeros and ones
    
    Returns:
    A NumPy array that is the matrix of synaptic weigths (J), 
    whose elements are computed as:
    J_ij = W_ij*Z[i]*Z[j]

    Note that if W_ij is the connectivity matrix, the resulting matrix 
    of synaptic strengths (J) will have only strengthed synapses on
    existing connections 

    Example:
    >>> from network import topology
    >>> from firings import Pattern, generate
    >>> from plasticity import clipped_Hebbian
    >>> W = topology(n = 5, c = 0.2)
    >>> Z = Pattern(n = 5, a = 0.1)
    >>> Y = generate(Z, m=40)
    >>> J = clipped_Hebbian(Z, Y)
    """
    # create an empty matrix
    J = np.zeros(W.shape, dtype=int)

    # iterate among all m patterns in pattern
    for pattern in range(len(Z)):
        J += W * np.outer(Z[pattern], Z[pattern]) # 124 ms per loop
        J[J>1] = 1 # clip it!

    return J
